import threading,json,hashlib,os

VIRTUAL_NODES_PER_SHARD = 100  # 每个物理分片对应100个虚拟节点
THREAD_NUMS = 1 
FACE_DATR_DIR = "face.data"
locks = []
face_data_list = []
for i in range(THREAD_NUMS):
    locks.append(threading.Lock())  
    face_data_list.append([])

class FaceData:
    def __init__(self, face_encoding, uuid:str,name:str):
        self.face_encoding = face_encoding
        self.name = name
        self.uuid = uuid

def init():
    #判断文件是否存在，不存在则创建
    if not os.path.exists(FACE_DATR_DIR):
        file = open(FACE_DATR_DIR, "w", encoding="utf-8")
        file.close()
    with open(FACE_DATR_DIR, 'r', encoding='utf-8') as file:
        lines = file.readlines()
        for line in lines:
            face_data = json.loads(line.strip())
            index = get_shard_with_virtual(face_data["uuid"])
            add_face_data(index,face_data)

def add_face_data(index,face_data):
    with locks[index]:  # 自动获取和释放锁
        face_data_list[index].append(face_data)

def get_face_dataList(index):
    return face_data_list[index].copy()  # 返回列表的副本，避免外部修改



# 人脸数据入库
def save(face_data:FaceData):
    file = open(FACE_DATR_DIR, "a", encoding="utf-8")
    file.write(json.dumps(face_data)+'\n')
    file.close()
    index = get_shard_with_virtual(face_data["uuid"])
    add_face_data(index,face_data)

# 获取物理分片ID
def get_shard_with_virtual(key: str) -> int:
    total_virtual = THREAD_NUMS * VIRTUAL_NODES_PER_SHARD
    virtual_id = get_shard_id(key, total_virtual)
    return virtual_id // VIRTUAL_NODES_PER_SHARD

def get_shard_id(key: str, total_shards: int) -> int:
    # 使用 SHA-1 哈希生成160位整数
    hash_obj = hashlib.sha1(key.encode('utf-8'))
    hex_digest = hash_obj.hexdigest()
    # 转换为十进制整数
    hash_int = int(hex_digest, 16)
    # 取模计算分片ID
    return hash_int % total_shards